var bum = bum || {};
bum.isNull = function(val) {
	return val === null || val === undefined;
}
bum.isDebug = false;

/* LISTENER */
bum.listener = {
	_listenters : {},

	add : function(evt, action) {
		if (bum.isNull(bum.listener._listenters[evt])) {
			bum.listener._listenters[evt] = [];
		}
		bum.listener._listenters[evt].push(action);
	},

	fire : function(evt, data) {
		if (bum.isNull(bum.listener._listenters[evt])) {
			return;
		}
		for (var len = bum.listener._listenters[evt].length, i = 0; i < len; i++) {
			bum.listener._listenters[evt][i](data);
		}
	}
};

bum.page = {
	init : function() {
		$(window).on("popstate", function(e) {
			bum.page.loadPage(location.href, true);
		});

		$(document).on("click", "a, area", function() {
			var T = $(this);
			if (!T.hasClass('go-ext')) {
				var href = T.attr("href");
				return bum.page.go(href);
			}

			// clear
			T = null;
		});
	},

	ajaxLoad : function(html) {
		if ($(document).data('isPageBack')) {
			// là trang back, lấy scrollTop ra dùng
			var scrollTop = $(document).data('pageScrollTop');
			if (scrollTop) {
				$('body').scrollTop(scrollTop);
				$(document).removeData('pageScrollTop');
			}

			// xong lưu lại scrollTop trang trước, để back tiếp thì dùng
			if (history.state) {
				$(document).data('pageScrollTop', history.state.scroll);
			}
		}

		document.title = html.match(/<title>(.*?)<\/title>/)[1];

		bum.page.initPage();
	},
	initPage : function() {
		var page = $('main [role=page]');

		var css = page.attr('css');
		if (css) {
			$('#pageCssTag').attr('href', css);
		}

		var js = page.attr('js');
		if (js) {
			$.ajaxSetup({
				cache : true
			});
			$.getScript(js, function() {
				WEBAPP.load();
			});
		} else {
			WEBAPP.load();
		}
	},

	main : null,
	loadPage : function(href, isBack) {
		// unload js
		WEBAPP.unload();

		$(document).data('isPageBack', isBack);
		if (!isBack && history.state.scroll) {
			// là trang mới, giữ scrolltop trang trước
			$(document).data('pageScrollTop', history.state.scroll);
		}

		bum.page.main = bum.page.main || $('main');
		bum.page.main.empty().load(href + " main>*", bum.page.ajaxLoad);
	},

	go : function(href) {
		if (href.indexOf('#') === 0 || "0" === $(this).attr('state')) {
			// do nothing
		} else {
			if (history.pushState) {
				if (href.indexOf(document.domain) > -1 || href.indexOf('://') === -1) {
					if (href.indexOf('javascript:') !== 0) {
						var path = location.href;
						path = path.substring(7 + document.domain.length);

						if (path != href) {
							history.pushState({
								scroll : $(window).scrollTop()
							}, 'page', href);

							$('body').scrollTop($('main:first').offset().top)
							// .stop().animate({
							// scrollTop : $('main:first').offset().top
							// }, 500)
							;
						}

						bum.page.loadPage(href, false);
						// console.log(href);

						return false;
					}
				}
			}
		}
	}
};
$(function() {
//	bum.page.init();
	bum.acc.init();
});

/* ACC */
bum.acc = {
	init : function() {
		
	}
};

/* BOOTSTRAP AJAX TAB */
$(document).ready(function() {
	$(document).on('click touch', '.nav-tabs [data-toggle="tabajax"]', function() {
		var T = $(this);
		$(T.attr('href')).load(T.attr('ajax-href'), {
			ajax : 1
		});
		T.tab('show');

		// clear
		// T = null;
		return false;
	});
});

/* =============== END UTILS */

// =================================================
/**
 * COMMON LIB
 */
String.prototype.startsWith = function(str) {
	return (this.match("^" + str) == str)
};
String.prototype.endsWith = function(str) {
	return (this.match(str + "$") == str)
};
String.prototype.hashCode = function() {
	var hash = 0, i, ch;
	if (this.length == 0)
		return hash;
	for (i = 0, l = this.length; i < l; i++) {
		ch = this.charCodeAt(i);
		hash = ((hash << 5) - hash) + ch;
		hash |= 0; // Convert to 32bit integer
	}
	return hash;
};

/* APP EVENTS */
var WEBAPP = {
	load : function() {
		$('#pageLoading').fadeOut();
		var id = $('main [role=page]').attr('id');
		if (WEBAPP[id] != undefined && typeof WEBAPP[id] === "function") {
			WEBAPP[id]();
		}
	},

	unload : function() {
		$('#pageLoading').fadeIn();
		id = $('main [role=page]').attr('id');
		if (id) {
			id = id + 'Unload';
		}
		if (WEBAPP[id] != undefined && typeof WEBAPP[id] === "function") {
			WEBAPP[id]();
		}
	}
};
$(function() {
	WEBAPP.load();
});

WEBAPP['homeRedirect'] = function() {
	location.href = "/app/home/bum";
};

/**
 * FEATURES MUSIC PLAYER
 */
$(document).on('click touch', '.play-playlist-button', function() {
	$('#playlistPlayerWrap').show();

	var url = $(this).attr('playlist');
	$.post(url, function(playlist) {
		if (WEBAPP['jPlayer'] === undefined) {
			WEBAPP['jPlayer'] = new jPlayerPlaylist({
				jPlayer : "#mp3Player",
				cssSelectorAncestor : "#jPlaylistContainer"
			}, playlist, {
				ready : function() {
					WEBAPP['jPlayer'].play();
				},
				swfPath : "http://s2.cdn.bum.vn/api/lib/jplayer/js/jplayer.swf",
				solution : "flash, html",
				supplied : "mp3,m4a",
				wmode : "window",
				volume : 1,
				loop : true,
				smoothPlayBar : true,
				keyEnabled : false
			});
		} else {
			WEBAPP['jPlayer'].setPlaylist(playlist);
			setTimeout(function() {
				WEBAPP['jPlayer'].play(0);
			}, 1000);
		}
	});

	return false;
}).on('click touch', '.jp-playlist-toggle', function() {
	$(this).parent().find('.jp-playlist-con').slideToggle();
	return false;
}).on('click touch', '.more-items-button', function() {
	$(this).parent().addClass('more-items-loading').text('Loading...');
	$.post($(this).attr('href'), {
		ajax : 1
	}, function(html) {
		$('.more-items-loading').after(html).remove();
	});

	return false;
});

/* SWIPE EVENT */
(function($, window, undefined) {
	var $document = $(document), supportTouch = "ontouchend" in document, touchStartEvent = supportTouch ? "touchstart" : "mousedown", touchStopEvent = supportTouch ? "touchend" : "mouseup", touchMoveEvent = supportTouch ? "touchmove"
			: "mousemove";

	// setup new event shortcuts
	$.each(("touchstart touchmove touchend " + "swipe swipeleft swiperight ").split(" "), function(i, name) {

		$.fn[name] = function(fn) {
			return fn ? this.bind(name, fn) : this.trigger(name);
		};

		// jQuery < 1.8
		if ($.attrFn) {
			$.attrFn[name] = true;
		}
	});

	function triggerCustomEvent(obj, eventType, event, bubble) {
		var originalType = event.type;
		event.type = eventType;
		if (bubble) {
			$.event.trigger(event, undefined, obj);
		} else {
			$.event.dispatch.call(obj, event);
		}
		event.type = originalType;
	}

	// Also handles swipeleft, swiperight
	$.event.special.swipe = {

		// More than this horizontal displacement, and we will suppress scrolling.
		scrollSupressionThreshold : 30,

		// More time than this, and it isn't a swipe.
		durationThreshold : 1000,

		// Swipe horizontal displacement must be more than this.
		horizontalDistanceThreshold : 30,

		// Swipe vertical displacement must be less than this.
		verticalDistanceThreshold : 30,

		getLocation : function(event) {
			var winPageX = window.pageXOffset, winPageY = window.pageYOffset, x = event.clientX, y = event.clientY;

			if (event.pageY === 0 && Math.floor(y) > Math.floor(event.pageY) || event.pageX === 0 && Math.floor(x) > Math.floor(event.pageX)) {

				// iOS4 clientX/clientY have the value that should have been
				// in pageX/pageY. While pageX/page/ have the value 0
				x = x - winPageX;
				y = y - winPageY;
			} else if (y < (event.pageY - winPageY) || x < (event.pageX - winPageX)) {

				// Some Android browsers have totally bogus values for clientX/Y
				// when scrolling/zooming a page. Detectable since clientX/clientY
				// should never be smaller than pageX/pageY minus page scroll
				x = event.pageX - winPageX;
				y = event.pageY - winPageY;
			}

			return {
				x : x,
				y : y
			};
		},

		start : function(event) {
			var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event, location = $.event.special.swipe.getLocation(data);
			return {
				time : (new Date()).getTime(),
				coords : [ location.x, location.y ],
				origin : $(event.target)
			};
		},

		stop : function(event) {
			var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event, location = $.event.special.swipe.getLocation(data);
			return {
				time : (new Date()).getTime(),
				coords : [ location.x, location.y ]
			};
		},

		handleSwipe : function(start, stop, thisObject, origTarget) {
			if (stop.time - start.time < $.event.special.swipe.durationThreshold && Math.abs(start.coords[0] - stop.coords[0]) > $.event.special.swipe.horizontalDistanceThreshold
					&& Math.abs(start.coords[1] - stop.coords[1]) < $.event.special.swipe.verticalDistanceThreshold) {
				var direction = start.coords[0] > stop.coords[0] ? "swipeleft" : "swiperight";

				triggerCustomEvent(thisObject, "swipe", $.Event("swipe", {
					target : origTarget,
					swipestart : start,
					swipestop : stop
				}), true);
				triggerCustomEvent(thisObject, direction, $.Event(direction, {
					target : origTarget,
					swipestart : start,
					swipestop : stop
				}), true);
				return true;
			}
			return false;

		},

		// This serves as a flag to ensure that at most one swipe event event is
		// in work at any given time
		eventInProgress : false,

		setup : function() {
			var events, thisObject = this, $this = $(thisObject), context = {};

			// Retrieve the events data for this element and add the swipe context
			events = $.data(this, "mobile-events");
			if (!events) {
				events = {
					length : 0
				};
				$.data(this, "mobile-events", events);
			}
			events.length++;
			events.swipe = context;

			context.start = function(event) {

				// Bail if we're already working on a swipe event
				if ($.event.special.swipe.eventInProgress) {
					return;
				}
				$.event.special.swipe.eventInProgress = true;

				var stop, start = $.event.special.swipe.start(event), origTarget = event.target, emitted = false;

				context.move = function(event) {
					if (!start) {
						return;
					}

					stop = $.event.special.swipe.stop(event);
					if (!emitted) {
						emitted = $.event.special.swipe.handleSwipe(start, stop, thisObject, origTarget);
						if (emitted) {

							// Reset the context to make way for the next swipe event
							$.event.special.swipe.eventInProgress = false;
						}
					}
					// prevent scrolling
					if (Math.abs(start.coords[0] - stop.coords[0]) > $.event.special.swipe.scrollSupressionThreshold) {
						event.preventDefault();
					}
				};

				context.stop = function() {
					emitted = true;

					// Reset the context to make way for the next swipe event
					$.event.special.swipe.eventInProgress = false;
					$document.off(touchMoveEvent, context.move);
					context.move = null;
				};

				$document.on(touchMoveEvent, context.move).one(touchStopEvent, context.stop);
			};
			$this.on(touchStartEvent, context.start);
		},

		teardown : function() {
			var events, context;

			events = $.data(this, "mobile-events");
			if (events) {
				context = events.swipe;
				delete events.swipe;
				events.length--;
				if (events.length === 0) {
					$.removeData(this, "mobile-events");
				}
			}

			if (context) {
				if (context.start) {
					$(this).off(touchStartEvent, context.start);
				}
				if (context.move) {
					$document.off(touchMoveEvent, context.move);
				}
				if (context.stop) {
					$document.off(touchStopEvent, context.stop);
				}
			}
		}
	};
	$.each({
		swipeleft : "swipe.left",
		swiperight : "swipe.right"
	}, function(event, sourceEvent) {

		$.event.special[event] = {
			setup : function() {
				$(this).bind(sourceEvent, $.noop);
			},
			teardown : function() {
				$(this).unbind(sourceEvent);
			}
		};
	});

})(jQuery, this);

// $(document).on('swiperight', function(e) {
// history.back();
// });
